package com.miszczu.dao;

import java.util.ArrayList;
import java.util.List;

import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Repository;

import com.miszczu.model.Users;
import com.miszczu.utils.CustomHibernateSupport;

@Repository
public class UsersDaoImpl extends CustomHibernateSupport implements UsersDao {

	private DetachedCriteria getUsersForClassCriteria(String userType, Integer classId) {
		
		DetachedCriteria crit = DetachedCriteria.forClass(Users.class);
		
		// find by class:
		DetachedCriteria classesCrit = crit.createCriteria("classeses");
		classesCrit.add(Restrictions.eq("classId", classId));
		
		// find by account type:
		DetachedCriteria accountTypesCrit = crit.createCriteria("accounttypes");
		accountTypesCrit.add(Restrictions.eq("accountType", userType));
		
		return crit;
		
	}
	
	public Long getNumberOfUsersForClass(String userType, Integer classId) {
		
		DetachedCriteria crit = this.getUsersForClassCriteria(userType, classId);
		crit.setProjection(Projections.rowCount());
		
		List<Long> numberOfRowsList = getHibernateTemplate().findByCriteria(crit);
		
		return numberOfRowsList.get(0);
	}

	public List<Users> getUsersForsClass(String userType, Integer classId) {
		
		List<Object[]> list = getSession().createQuery("from Users as u inner join u.classeses as c left join u.accounttypes as a " +
				"where a.accountType = :userType and c.classId = :classId order by u.lastName ASC, u.firstName ASC")
				.setString("userType", userType)
				.setInteger("classId", classId)
				.list();
		
		ArrayList<Users> users = new ArrayList<Users>();
		for(Object[] obj : list) {
			users.add((Users) obj[0]);
		}
		
		return users;
		
		//DetachedCriteria crit = this.getUsersForClassCriteria(userType, classId);
		//crit.addOrder(Order.asc("lastName"));
		
		//return getHibernateTemplate().findByCriteria(crit);
	}

	public void save(Users user) {
		
		getHibernateTemplate().save(user);
	}

	public void update(Users user) {
		
		getHibernateTemplate().update(user);
		
	}

	public List<Users> getAllUsers(String type) {
		
		// naprawde zjebane gowno:
		
		List<Object[]> toSplit = getHibernateTemplate().find("from Users as u join u.accounttypes as atypes where atypes.accountType = ?", type);
		
		List<Users> users = new ArrayList<Users>();
		for(Object[] splitted : toSplit) {
			users.add((Users) splitted[0]);
		}
		
		return users;
		
//		DetachedCriteria crit = DetachedCriteria.forClass(Users.class);
//		crit.addOrder(Order.asc("lastName"));
//		
//		DetachedCriteria addCrit = crit.createCriteria("accounttypes");
//		addCrit.add(Restrictions.eq("accountType", type));
//		
//		return getHibernateTemplate().findByCriteria(crit);
		
		
	}

	public Users getOne(Integer id) {

		return getHibernateTemplate().get(Users.class, id);
		
	}

	public void delete(Users user) {

		getHibernateTemplate().delete(user);
		
	}

	public Users getOneByLogin(String login) {

		DetachedCriteria crit = DetachedCriteria.forClass(Users.class);
		crit.add(Restrictions.eq("userLogin", login));
		
		List<Users> users = getHibernateTemplate().findByCriteria(crit);
		
		if(users.isEmpty()) {
			return null;
		} else {
			return users.get(0);
		}
		
	}

}
